const { Controller } = require('egg');

class ChatController extends Controller {
  // ws链接
  async connect() {
    const { ctx, app } = this;
    if (!ctx.websocket) {
      ctx.throw(400, '非法访问');
    }

    console.log(`连接数: ${app.ws.clients.size}`);

    // 监听接收消息和关闭socket
    ctx.websocket
      .on('message', (msg) => {
        console.log('接收消息', msg);
      })
      .on('close', (code, reason) => {
        console.log('websocket 关闭', code, reason);
      });
  }
  // 发送消息
  async send() {
    const { ctx, app, service } = this;
    // 1. 拿到当前用户id
    let id = ctx.authUser.id;
    //  2. 验证参数
    ctx.validate({
      to_id: {
        type: 'int',
        required: true,
        desc: '接收人/群id'
      },
      chat_type: {
        type: 'string',
        required: true,
        range: {
          in: ['user', 'group']
        },
        desc: '接收类型'
      },
      type: {
        type: 'string',
        required: true,
        range: {
          in: ['text', 'emo', 'image', 'video', 'card', 'map']
        },
        desc: '消息类型'
      },
      data: {
        type: 'string',
        required: true,
        desc: '消息内容'
      },
      options: {
        type: 'string',
        required: true
      }
    });
    // 3. 获得传递过来的参数
    let { to_id, chat_type, type, data, options } = ctx.request.body;
    console.log(to_id, chat_type, type, data, options);
    // 4. 判断消息类型
    if (chat_type === 'user') {
      // 4.1 私聊
      // 4.2 验证好友是否存在，并且对方没有把你拉黑
      const friend = await app.model.Friend.findOne({
        where: {
          user_id: to_id,
          friend_id: id
        },
        include: [
          {
            model: app.model.User,
            as: 'userInfo',
            attributes: {
              exclude: ['password']
            }
          },
          {
            model: app.model.User,
            as: 'friendInfo',
            attributes: {
              exclude: ['password']
            }
          }
        ]
      });
      if (!friend) {
        ctx.throw(400, '该用户不存在');
      }
      if (friend.userInfo.status === 0) {
        ctx.throw(400, '用户已被禁用');
      }
      let op = {};
      if (type === 'card' || type === 'map') {
        op = JSON.parse(options) || {};
      }
      // 4.3 组织数据格式
      let message = {
        id: new Date().getTime(), // 唯一id，后端生成唯一id
        friend_id: friend.id, // 好友id
        from_avatar: friend.friendInfo.avatar, // 发送者头像
        from_name: friend.nickname, // 发送者昵称
        from_id: id, // 发送者id
        to_id, // 接收人/群 id
        to_name: friend.userInfo.nickname
          ? friend.userInfo.nickname
          : friend.userInfo.username, // 接收人/群 名称
        to_avatar: friend.userInfo.avatar, // 接收人/群 头像
        chat_type: 'user', // 接收类型
        type, // 消息类型
        data, // 消息内容
        options: op, // 其他参数
        create_time: new Date().getTime(), // 创建时间
        isremove: 0 // 是否撤回
      };
      // 4.4 发送消息
      ctx.sendMessage(to_id, message);
      // 将消息存到自己的聊天记录中  格式为 chatlog_当前用户id_消息类型_对方用户id
      service.cache.setList(`chatlog_${id}_${chat_type}_${to_id}`, message);
      // 4.5 返回消息
      ctx.success(friend);
    } else {
      // 4.6 验证群聊是否存在
      const group = await app.model.Group.findOne({
        where: {
          id: to_id,
          status: 1
        },
        include: [
          {
            model: app.model.GroupUser,
            attributes: ['user_id', 'nickname']
          }
        ]
      });
      if (!group) {
        ctx.throw(400, '该群不存在或已被封禁');
      }
      // 4.7 验证我是否为群成员
      let index = group.group_users.findIndex((item) => item.user_id === id);
      if (index === -1) {
        return ctx.apiFail('你不是该群的成员');
      }
      // 4.8 格式整理
      let from_name = group.group_users[index].nickname;
      let op = {};
      if (type === 'card' || type === 'map') {
        op = JSON.parse(options) || {};
      }
      let message = {
        id: new Date().getTime(), // 唯一id，后端生成唯一id
        from_avatar: ctx.authUser.avatar, // 发送者头像
        from_name: from_name || ctx.authUser.nickname || ctx.authUser.username, // 发送者昵称
        from_id: id, // 发送者id
        to_id, // 接收人/群 id
        to_name: group.name, // 接收人/群 名称
        to_avatar: group.avatar, // 接收人/群 头像
        chat_type: 'group', // 接收类型
        type, // 消息类型
        data, // 消息内容
        options: op, // 其他参数
        create_time: new Date().getTime(), // 创建时间
        isremove: 0, // 是否撤回
        group: group
      };
      // 4.9 发送消息
      group.group_users.forEach((item) => {
        if (item.user_id !== id) {
          ctx.sendMessage(item.user_id, message);
        }
      });
      ctx.success(message);
    }
  }
  // 获取离线消息
  async getOfflineMessage() {
    const { ctx, app, service } = this;
    console.log(ctx.authUser.id);
    let id = ctx.authUser.id;
    let key = 'getmessage_' + id;
    let list = await service.cache.getList(key);
    // 批量推送
    list.forEach(async (message) => {
      let d = JSON.parse(message);
      console.log(d);
      ctx.sendMessage(id, d, 'offline');
    });
    // 清除离线消息
    await service.cache.remove(key);
    ctx.success('获取成功');
  }
}
module.exports = ChatController;
